import uuid
from datetime import timedelta

from fastapi import APIRouter, Depends
from loguru import logger
from sqlalchemy.orm import Session
from starlette.requests import Request

from backend_module.jsonvo.authentication_vo import BackendAuthLoginModel, BackendGetUserInfoRequest
from backend_module.service.sys_login_service import SysLoginService, create_access_token
from config.env import JwtConfig
from config.get_db import get_db
from utils.response_util import LoginException, response_backend_200, \
    response_backend_500, response_backend_400

backendLoginMapper = APIRouter()
sys_login_service = SysLoginService()


@backendLoginMapper.post('/backend/login')
async def login(request: Request, params: BackendAuthLoginModel,
                query_db: Session = Depends(get_db)):
    try:
        result = sys_login_service.sys_account_login_service(query_db, params.username, params.password)

    except LoginException as e:
        return response_backend_400(data="", message=e.message)

    try:
        access_token_expires = timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES)
        session_id = str(uuid.uuid4())
        access_token = create_access_token(
            data={
                "user_id": result.user_id,
                "session_id": session_id,
            },
            expires_delta=access_token_expires
        )
        await request.app.state.redis.set(f'backend_access_token:{session_id}', access_token,
                                          ex=timedelta(minutes=JwtConfig.ACCESS_TOKEN_EXPIRE_MINUTES))

        logger.info('登录成功')
        # 判断请求是否来自于api文档，如果是返回指定格式的结果，用于修复api文档认证成功后token显示undefined的bug
        request_from_swagger = request.headers.get('referer').endswith('docs') if request.headers.get(
            'referer') else False
        request_from_redoc = request.headers.get('referer').endswith('redoc') if request.headers.get(
            'referer') else False
        if request_from_swagger or request_from_redoc:
            return {'accessToken': access_token, 'tokenType': 'Bearer', 'userId': result.user_id}
        return response_backend_200(
            data={'accessToken': access_token, 'tokenType': 'Bearer', 'userId': result.user_id},
            message='登录成功'
        )
    except Exception as e:
        logger.exception(e)
        return response_backend_500(data="", message='服务器异常，请联系管理员')


@backendLoginMapper.post('/backend/userinfo')
async def get_user_info(request: Request, query_model: BackendGetUserInfoRequest, query_db: Session = Depends(get_db)):
    if query_model.user_id <= 0:
        return response_backend_400(data='')
    result = sys_login_service.get_user_by_id_service(query_db, query_model.user_id)
    if result is None:
        return response_backend_500(data='', message='服务器异常，请联系管理员')
    else:
        return response_backend_200(data=result)

@backendLoginMapper.get('/backend/logout')
async def logout(request: Request):
    return response_backend_200(data='', message='退出系统成功')